#!/usr/bin/env python3

# 2016, Georg Sauthoff <mail@georg.so>, GPLv3+

import copy
import lxml
from lxml.builder import E
from lxml import etree
import re
import sys

# necessary for xpath
ns = etree.FunctionNamespace('http://check.sourceforge.net/ns')
ns.prefix='c'

# not necessary for xpath
#etree.register_namespace('c', 'http://check.sourceforge.net/ns')


# see also
# http://nelsonwells.net/2012/09/how-jenkins-ci-parses-and-displays-junit-output/
# for a discussion of the JUnit format, as used by Jenkins

def mk_testcase(case):
    name = case.xpath('./c:id')[0].text
    iteration = case.xpath('./c:iteration')[0].text
    if iteration != '0':
        name = name + '_' + iteration
    fn = case.xpath('./c:fn')[0].text
    fn = re.sub('\.[^.]+:.+$', '', fn)
    result = case.attrib['result']
    if result == 'success':
        duration = case.xpath('./c:duration')[0].text
    else:
        duration = '0'
    r = E('testcase', name=name, classname=fn, time=duration)
    if result == 'failure':
        message = case.xpath('./c:message')[0].text
        err = E('error', message=message)
        r.append(err)
    return r

def mk_testsuite(suite, timestamp):
    title = suite.xpath('./c:title')[0]
    tests = suite.xpath('./c:test')
    failures = suite.xpath('./c:test[@result="failure"]')
    r = E('testsuite', name=title.text, timestamp=timestamp,
          tests=str(tests.__len__()), failures=str(failures.__len__()))
    for test in tests:
        r.append(mk_testcase(test))
    return r

def mk_testsuites_P(r, ts):
    datetime = ts.xpath('./c:datetime')[0]
    timestamp = datetime.text.replace(' ', 'T')
    suites = ts.xpath('./c:suite')
    for suite in suites:
        r.append(mk_testsuite(suite, timestamp))
    return r

def mk_testsuites(fs):
    if type(fs) is list:
        filenames = fs
    else:
        filenames = [fs]
    r = E('testsuites')
    for filename in filenames:
        d = etree.parse(filename)
        root = d.getroot()
        mk_testsuites_P(r, root)
    return r

def main(argv):
    if '-h' in argv or '--help' in argv:
        print('''Convert one or many libcheck XML reports into JUnit
compatible output (as understood by Jenkins)''')
        return 0
    print('''<!-- generated by check2junit.py
        the libcheck-XML to JUnit-Jenkins-style-XML converter -->''')
    etree.dump(mk_testsuites(argv[1:]))
    return 0


if __name__ == '__main__':
    sys.exit(main(sys.argv))
